<!--
 * @Description:
 * @Author: dh
 * @Date: 2022-01-21 13:41:19
 * @LastEditors: dh
 * @LastEditTime: 2023-01-04 09:23:36
-->
<template>
	<div ref="el" @click="click">click</div>
	<div ref="el" @touchmove="touch">touch</div>
</template>

<script lang="ts">
/* eslint-disable */
import { defineComponent, nextTick, onMounted, reactive, ref, PropType } from 'vue';

interface result<T> {
	msg: string;
	code: number;
	data?: T;
}
interface userInfo<T> {
	name: string;
	age?: T;
	[index: string]: string | number[] | undefined | T;
}

export default defineComponent({
	// 约束 prop
	props: {
		userInfo: {
			type: Object as PropType<userInfo<number>>, // 约束构造函数类型，可以通过 PropType 定义
			required: true,
		},
	},
	setup() {
		const obj1: result<null> = { msg: '1', code: 200, data: null };
		const obj2: result<number> = { msg: '1', code: 200, data: 123 };
		const obj3: result<userInfo<number>> = {
			msg: '1',
			code: 200,
			data: { name: 'deng', age: 20 },
		};
		const obj4: result<userInfo<string>> = {
			msg: '1',
			code: 200,
			data: { name: 'deng', age: '20' },
		};

		/* ****将某个类型里的属性全部变为必选项。只是第一层必须，******** */
		const obj5: Required<userInfo<number>> = reactive({
			name: 'deng',
			age: 20,
		});
		const obj52: Required<result<userInfo<string>>> = {
			msg: '1',
			code: 200,
			data: { name: 'deng' }, // 这里age是第二层数据，任然可以不用写
		};

		/* ********** 特殊内置类型 ************** */
		const el = ref<HTMLElement>();
		// const point = ref<HTMLDivElement | null>(null);
		onMounted(() => {
			nextTick(() => {
				console.log((el.value as HTMLElement).style);
			});
		});
		const click = (e: Event) => {
			console.log(e);
		};
		const touch = (e: TouchEvent) => {
			console.log(e);
		};

		/* *********** interface继承 ***************** */
		interface A {
			name: string;
		}
		interface B {
			age: number;
		}
		interface C extends A, B {
			sex: string;
		}

		const p: C = { name: 'string', age: 20, sex: 'boy' };

		/* *********** interface和type分别定义函数 ***************** */
		interface Fun {
			(x: number, y: number, desc?: string): string;
		}
		type Fun2 = (x: number, y: number, desc?: string) => string;

		const sum: Fun | Fun2 = (x, y) => `${x + y}`;
		console.log(sum(1, 2));

		/* *********** interface和type 区别 ************** */
		// 基本类型
		type name = string;
		// 联合类型
		interface Obj1 {
			age: number;
		}
		interface Obj2 {
			sex: string;
		}
		type user1Type = Obj1 | Obj2; // 类似||
		type user2Type = Obj1 & Obj2; // 类似&&
		const user1: user1Type = { age: 20 };
		const user2: user2Type = { age: 20, sex: 'boy' };

		// 元祖类型
		type list = [Obj1, Obj2];
		const arr: list = [{ age: 20 }, { sex: 'boy' }];

		/* *********** class  ****************** */
		interface Entity {
			title?: string;
			log(): void;
		}
		class Post implements Entity {
			title: string;

			constructor(title: string) {
				this.title = title;
			}

			log(): void {
				console.log(this.title);
			}
		}

		return { el, click, touch };
	},
});
</script>

<style scoped></style>
